package com.kou.backend.util;

import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 文件操作工具类
 *
 * @author: kou
 * @since: 2025/6/26 14:31
 */
@Slf4j
public class FileUtils {

    /**
     * 计算文件MD5（可选，用于秒传）
     */
    public static String calculateMd5(MultipartFile file) throws IOException {
        try (InputStream is = file.getInputStream()) {
            return DigestUtils.md5Hex(is);
        }
    }

    /**
     * 递归删除目录
     *
     * @param file 文件或目录
     */
    public static void deleteDirectory(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    deleteDirectory(f);
                }
            }
        }
        // 删除文件或空文件夹
        if (!file.delete()) {
            throw new RuntimeException("无法删除文件或目录: " + file.getAbsolutePath());
        }
    }


    /**
     * 通用文件输出
     *
     * @param inputStream 文件输入流
     * @param storagePath 相对路径（用于推断类型）
     * @param response    HttpServletResponse
     * @param disposition "inline" | "attachment"
     * @throws IOException IO异常
     */
    public static void writeFileToResponse(InputStream inputStream, String storagePath, HttpServletResponse response, String disposition) throws IOException {
        // 推断Content-Type
        String contentType = Files.probeContentType(Paths.get(storagePath));
        response.setContentType(contentType != null ? contentType : "application/octet-stream");

        // 设置 Cache-Control: 图片/视频缓存，其他不缓存
        if (contentType != null && (contentType.startsWith("image/") || contentType.startsWith("video/"))) {
            response.setHeader("Cache-Control", "public, max-age=3600");
        } else {
            response.setHeader("Cache-Control", "no-store, must-revalidate");
        }

        // 设置 Content-Disposition
        String fileName = storagePath.substring(storagePath.lastIndexOf("/") + 1);
        response.setHeader("Content-Disposition", disposition + "; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");

        // 写流
        IOUtils.copy(inputStream, response.getOutputStream());
        response.flushBuffer();
        inputStream.close();

        log.info("文件输出完成，路径: {}, disposition: {}, Content-Type: {}", storagePath, disposition, contentType);
    }

    /**
     * 通用文件输出 快捷方法：预览
     */
    public static void previewToResponse(InputStream inputStream, String storagePath, HttpServletResponse response) throws IOException {
        writeFileToResponse(inputStream, storagePath, response, "inline");
    }

    /**
     * 通用文件输出 快捷方法：下载
     */
    public static void downloadToResponse(InputStream inputStream, String storagePath, HttpServletResponse response) throws IOException {
        writeFileToResponse(inputStream, storagePath, response, "attachment");
    }
}
